/**
 * SIX VULN - http://code.google.com/p/six-vuln/
 * Copyright (C) 2006
 *   National Institute of Advanced Industrial Science and Technology (AIST)
 *   Registration Number: H20PRO-863
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jp.go.aist.six.vuln.model.scap.vulnerability;

import java.util.ArrayList;
import java.util.Collection;
import jp.go.aist.six.util.persist.Persistable;
import jp.go.aist.six.vuln.model.scap.core.CheckReferenceType;
import jp.go.aist.six.vuln.model.scap.core.ReferenceType;
import jp.go.aist.six.vuln.model.scap.cpe.PlatformType;
import jp.go.aist.six.vuln.model.scap.cvss.CvssImpactType;
import com.github.jmkgreen.morphia.annotations.Entity;
import com.github.jmkgreen.morphia.annotations.Id;



/**
 *
 * @author	Akihito Nakamura, AIST
 * @version $Id: VulnerabilityType.java 599 2013-06-12 07:30:16Z nakamura5akihito@gmail.com $
 */
//@Document( collection="nvd.vulnerability" )     //Spring
@Entity( "nvd.vulnerability" )                  //Morphia
public class VulnerabilityType
    implements Persistable<String>
{

    private OsvdbExtensionType  osvdbExt;
    //{0..1}

    private final Collection<PlatformType>  vulnerableConfiguration = new ArrayList<PlatformType>();
    //{0..*}

    private VulnerableSoftwareType  vulnerableSoftwareList;
    //{0..1}

    //TODO: XSD model, choice
    private String  cveId;
    //{cve:cveNamePatternType, 0..1}

    private String  cceId;
    //{ccc:cccNamePatternType, 0..1}

    //{xsd:dateTime, 0..1}
    private String  discoveredDatetime;
    private String  disclosureDatetime;
    private String  exploitPublishDatetime;
    private String  publishedDatetime;
    private String  lastModifiedDatetime;
//    private Date  discoveredDatetime;
//    private Date  disclosureDatetime;
//    private Date  exploitPublishDatetime;
//    private Date  publishedDatetime;
//    private Date  lastModifiedDatetime;

    private CvssImpactType  cvss;
    //{0..1}

    private SecurityProtectionType  securityProtection;
    //{0..1}

    private final Collection<CheckReferenceType>  assessmentCheck = new ArrayList<CheckReferenceType>();
    //{0..*}

    private final Collection<CweReferenceType>  cwe = new ArrayList<CweReferenceType>();
    //{0..*}

    private final Collection<VulnerabilityReferenceType>  references = new ArrayList<VulnerabilityReferenceType>();
    //{0..*}

    private final Collection<FixActionType>  fixAction = new ArrayList<FixActionType>();
    //{0..*}

    /**
     * Denotes a scanner and required configuration
     * that is capable of detecting the referenced vulnerability.
     * May also be an OVAL definition and omit scanner name.
     */
    private final Collection<ToolConfigurationType>  scanner = new ArrayList<ToolConfigurationType>();

    private String  summary;
    //{0..1}

    private final Collection<ReferenceType>  technicalDescription = new ArrayList<ReferenceType>();
    //{0..*}

    /**
     * This element should ultimately be held in a threat model.
     */
    private final Collection<ReferenceType>  attackScenario = new ArrayList<ReferenceType>();

    @Id //MongoDB
    private String  id;
    //{vulnerabilityIdType === xsd:token, required}



    /**
     * Constructs an instance.
     */
    public VulnerabilityType()
    {
    }



    /**
     */
    public OsvdbExtensionType getOsvdbExt()
    {
        return osvdbExt;
    }


    public void setOsvdbExt(
                    final OsvdbExtensionType osvdbExt
                    )
    {
        this.osvdbExt = osvdbExt;
    }



    /**
     */
    public Collection<PlatformType> getVulnerableConfiguration()
    {
        return vulnerableConfiguration;
    }


    public void setVulnerableConfiguration(
                    final Collection<? extends PlatformType> vulnerableConfiguration_list
                    )
    {
        if (vulnerableConfiguration_list != vulnerableConfiguration) {
            vulnerableConfiguration.clear();
            if (vulnerableConfiguration_list != null) {
                vulnerableConfiguration.addAll( vulnerableConfiguration_list );
            }
        }
    }



    /**
     */
    public VulnerableSoftwareType getVulnerableSoftwareList()
    {
        return vulnerableSoftwareList;
    }


    public void setVulnerableSoftwareList(
                    final VulnerableSoftwareType vulnerableSoftwareList
                    )
    {
        this.vulnerableSoftwareList = vulnerableSoftwareList;
    }



    /**
     */
    public String getCveId()
    {
        return cveId;
    }


    public void setCveId(
                    final String cveId
                    )
    {
        this.cveId = cveId;
    }



    /**
     */
    public String getCceId()
    {
        return cceId;
    }


    public void setCceId(
                    final String cceId
                    )
    {
        this.cceId = cceId;
    }



    /**
     */
    public String getDiscoveredDatetime()
    {
        return discoveredDatetime;
    }


    public void setDiscoveredDatetime(
                    final String discoveredDatetime
                    )
    {
        this.discoveredDatetime = discoveredDatetime;
    }



    /**
     */
    public String getDisclosureDatetime()
    {
        return disclosureDatetime;
    }


    public void setDisclosureDatetime(
                    final String disclosureDatetime
                    )
    {
        this.disclosureDatetime = disclosureDatetime;
    }



    /**
     */
    public String getExploitPublishDatetime()
    {
        return exploitPublishDatetime;
    }


    public void setExploitPublishDatetime(
                    final String exploitPublishDatetime
                    )
    {
        this.exploitPublishDatetime = exploitPublishDatetime;
    }



    /**
     */
    public String getPublishedDatetime()
    {
        return publishedDatetime;
    }


    public void setPublishedDatetime(
                    final String publishedDatetime
                    )
    {
        this.publishedDatetime = publishedDatetime;
    }



    /**
     */
    public String getLastModifiedDatetime()
    {
        return lastModifiedDatetime;
    }


    public void setLastModifiedDatetime(
                    final String lastModifiedDatetime
                    )
    {
        this.lastModifiedDatetime = lastModifiedDatetime;
    }



    /**
     */
    public void setCvss(
                    final CvssImpactType cvss
                    )
    {
        this.cvss = cvss;
    }


    public CvssImpactType getCvss()
    {
        return cvss;
    }



    /**
     */
    public SecurityProtectionType getSecurityProtection()
    {
        return securityProtection;
    }


    public void setSecurityProtection(
                    final SecurityProtectionType securityProtection
                    )
    {
        this.securityProtection = securityProtection;
    }



    /**
     */
    public Collection<CheckReferenceType> getAssessmentCheck()
    {
        return assessmentCheck;
    }


    public void setAssessmentCheck(
                    final Collection<? extends CheckReferenceType> assessmentCheck_list
                    )
    {
        if (assessmentCheck_list != assessmentCheck) {
            assessmentCheck.clear();
            if (assessmentCheck_list != null) {
                assessmentCheck.addAll( assessmentCheck_list );
            }
        }
    }



    /**
     */
    public Collection<CweReferenceType> getCwe()
    {
        return cwe;
    }


    public void setCwe(
                    final Collection<? extends CweReferenceType> cwe_list
                    )
    {
        if (cwe_list != cwe) {
            cwe.clear();
            if (cwe_list != null) {
                cwe.addAll( cwe_list );
            }
        }
    }



    /**
     */
    public Collection<VulnerabilityReferenceType> getReferences()
    {
        return references;
    }


    public void setReferences(
                    final Collection<? extends VulnerabilityReferenceType> reference_list
                    )
    {
        if (reference_list != references) {
            references.clear();
            if (reference_list != null) {
                references.addAll( reference_list );
            }
        }
    }



    /**
     */
    public Collection<FixActionType> getFixAction()
    {
        return fixAction;
    }


    public void setFixAction(
                    final Collection<? extends FixActionType> fixAction_list
                    )
    {
        if (fixAction_list != fixAction) {
            fixAction.clear();
            if (fixAction_list != null) {
                fixAction.addAll( fixAction_list );
            }
        }
    }



    /**
     */
    public Collection<ToolConfigurationType> getScanner()
    {
        return scanner;
    }


    public void setScanner(
                    final Collection<? extends ToolConfigurationType> scanner_list
                    )
    {
        if (scanner_list != scanner) {
            scanner.clear();
            if (scanner_list != null) {
                scanner.addAll( scanner_list );
            }
        }
    }



    /**
     */
    public String getSummary()
    {
        return summary;
    }


    public void setSummary(
                    final String summary
                    )
    {
        this.summary = summary;
    }



    /**
     */
    public Collection<ReferenceType> getTechnicalDescription()
    {
        return technicalDescription;
    }


    public void setTechnicalDescription(
                    final Collection<? extends ReferenceType> technicalDescription_list
                    )
    {
        if (technicalDescription_list != technicalDescription) {
            technicalDescription.clear();
            if (technicalDescription_list != null) {
                technicalDescription.addAll( technicalDescription_list );
            }
        }
    }



    /**
     */
    public Collection<ReferenceType> getAttackScenario()
    {
        return attackScenario;
    }


    public void setAttackScenario(
                    final Collection<? extends ReferenceType> attackScenario_list
                    )
    {
        if (attackScenario_list != attackScenario) {
            attackScenario.clear();
            if (attackScenario_list != null) {
                attackScenario.addAll( attackScenario_list );
            }
        }
    }



    /**
     */
    public void setId(
                    final String id
                    )
    {
        this.id = id;
    }


    public String getId()
    {
        return id;
    }



    //*********************************************************************
    //  Persistable
    //*********************************************************************

    public void setPersistentID(
                    final String id
                    )
    {
        setId( id );
    }


    public String getPersistentID()
    {
        return getId();
    }



    //*********************************************************************
    //  java.lang.Object
    //*********************************************************************

    @Override
    public int hashCode()
    {
        final int prime = 37;
        int result = 17;

        final String  id = getId();
        result = prime * result + ((id == null) ? 0 : id.hashCode());

        return result;
    }



    @Override
    public boolean equals(
                    final Object obj
                    )
    {
        if (this == obj) {
            return true;
        }

        if (!(obj instanceof VulnerabilityType)) {
            return false;
        }

        final VulnerabilityType  other = (VulnerabilityType)obj;

        final String   this_id =  this.getId();
        final String  other_id = other.getId();
        if (this_id == other_id
                        ||  (this_id != null  &&  this_id.equals( other_id ))) {
            return true;
        }

        return false;
    }



    @Override
    public String toString()
    {
        return "[id=" + getId()
                        + ", cveId=" + getCveId()
                        + ", publishedDatetime=" + getPublishedDatetime()
                        + ", lastModifiedDatetime=" + getLastModifiedDatetime()
                        + ", vulnerableConfiguration=" + getVulnerableConfiguration()
                        + ", vulnerableSoftware=" + getVulnerableSoftwareList()
                        + ", cvss=" + getCvss()
                        + ", summary=" + getSummary()
                        + "]";
    }

}
//VulnerabilityType
